﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XTYAPI.PLC
{
    /// <summary>
    /// 规范标准 IPC-SMEMA-9851
    /// </summary>
    public class SMEMA
    {
        #region 本机状态

        /// <summary>
        /// 设备绿灯状态
        /// </summary>
        public bool GreenLight { get; set; }
        /// <summary>
        /// 入料感应
        /// </summary>
        public bool InPutSernsor { get; set; }
        /// <summary>
        /// 出料感应
        /// </summary>
        public bool OutPutSensor { get; set; }
        /// <summary>
        /// 出料感应下降沿
        /// </summary>
        public F_TRIG F_TRIG_OutPutSensor { get;private set; } = new F_TRIG();
        /// <summary>
        /// 入料信号延时防抖
        /// </summary>
        public TON TonInPutSernsor { get; private set; } = new TON(2*100);
        /// <summary>
        /// 出料信号延时防抖
        /// </summary>
        public TON TonOutPutSensor { get; private set; } = new TON(2 * 100);
        /// <summary>
        /// 是否有报警
        /// </summary>
        public bool Error { get { return ErrInfo.Length > 0; } } 
        /// <summary>
        /// 报警内容
        /// </summary>
        public string ErrInfo { get; set; }

        #endregion

        #region 连接上料机
        /// <summary>
        /// 本机需要PCB pin1,2
        /// </summary>
        public bool ThisNeedPCB { get; set; }
        /// <summary>
        /// 上料机ok有料
        /// </summary>
        public bool UpReady { get; set; }
        /// <summary>
        /// 是否检测上料机有效
        /// </summary>
        public bool IsCheckUpReady { get; set; } = true;      
        /// <summary>
        /// 本机要料超时默认10秒
        /// </summary>
        public TON TonThisNeedPCBTimeOut { get; private set; } = new TON(100 * 100);
        /// <summary>
        /// 上料机Ready超时
        /// </summary>
        public TON UpReadyTimeOut   { get;private set; }=new TON(100 * 100);


        public enum 上料机
        {
            无任务,
            本机Ready,
            本机开始要料,
            本机要料完成
        }
        public 上料机 Enum上料机 { get; private set; } = 上料机.无任务;

        #endregion

        #region 连接下料机

        /// <summary>
        /// 下料机需要PCB pin1,2
        /// </summary>
        public bool DnNeedPCB { get; set; }
        /// <summary>
        /// 本机准备OK pin3,4
        /// </summary>
        public bool ThisReady { get; set; }
        /// <summary>
        /// 是否检测下料机长时间没料
        /// </summary>
        public bool IsCheckDnNeed { get; set; } = true;
        /// <summary>
        /// 下料机长时间不要料
        /// </summary>
        public TON DnNeedPCBTimeOut { get; set; } = new TON(100 * 1000);
        /// <summary>
        /// 出料超时，或卡板
        /// </summary>
        public TON TonThisOutPCBTimeOut { get; set; } = new TON(10*1000);
        public enum 下料机
        {
            无任务,
            本机Ready,
            本机开始出料,
            本机出料完成
        }
        public 下料机 Enum下料机 { get; private set; } = 下料机.无任务;

        #endregion

        #region 方法
        /// <summary>
        /// 计算Smema,死循环调用
        /// </summary>
        public void CalSmema()
        {
            try
            {
                #region 上料机处理
                switch (Enum上料机)
                {
                    case 上料机.无任务:
                        if (GreenLight && ThisNeedPCB && !Error)
                        {
                            Enum上料机 = 上料机.本机Ready;
                        }
                        break;

                    case 上料机.本机Ready:
                        UpReadyTimeOut.IN = !UpReady && IsCheckUpReady;//检测上料机是否准备好
                        if (UpReadyTimeOut.Q)
                        {
                            //上料机准备超时
                            ErrInfo = "上料机长时间没有准备好";
                            UpReadyTimeOut.IN = false;
                            Enum上料机 = 上料机.无任务;
                        }
                        else
                        {
                            Enum上料机 = 上料机.本机开始要料;
                        }
                        break;

                    case 上料机.本机开始要料:
                        TonInPutSernsor.IN = InPutSernsor;
                        TonThisNeedPCBTimeOut.IN = !InPutSernsor;
                        if (TonInPutSernsor.Q)
                        {
                            Enum上料机 = 上料机.本机要料完成;
                            TonInPutSernsor.IN = false;
                        }
                        else if (TonThisNeedPCBTimeOut.Q)
                        {
                            //上料机准备超时
                            ErrInfo = "本机要料超时，本机入料传感器长时间未感应到";
                            Enum上料机 = 上料机.无任务;
                            TonThisNeedPCBTimeOut.IN = false;
                        }
                        break;

                    case 上料机.本机要料完成:
                        ThisNeedPCB = false;
                        Enum上料机 = 上料机.无任务;
                        break;
                    default:
                        break;
                }
                #endregion

                #region 下料机处理

                switch (Enum下料机)
                {
                    case 下料机.无任务:
                        if (GreenLight && ThisReady)
                        {
                            Enum下料机 = 下料机.本机Ready;
                        }
                        break;

                    case 下料机.本机Ready:
                        DnNeedPCBTimeOut.IN = !DnNeedPCB && IsCheckDnNeed;//检测下料机是否一直没有要料
                        if (DnNeedPCBTimeOut.Q)
                        {
                            //上料机准备超时
                            ErrInfo = "本机准备好了很久，下料机长时间不要料";
                            DnNeedPCBTimeOut.IN = false;
                            Enum下料机 = 下料机.无任务;
                        }
                        else
                        {
                            Enum下料机 = 下料机.本机开始出料;
                        }
                        break;

                    case 下料机.本机开始出料:
                        TonOutPutSensor.IN = OutPutSensor;
                        TonThisOutPCBTimeOut.IN = OutPutSensor;
                        F_TRIG_OutPutSensor.CLK = TonOutPutSensor.Q;
                        if (F_TRIG_OutPutSensor.Q)//本机出料seneor
                        {
                            Enum下料机 = 下料机.本机出料完成;
                            TonInPutSernsor.IN = false;
                        }
                        else if (TonThisOutPCBTimeOut.Q)
                        {
                            //上料机准备超时
                            ErrInfo = "本机出料超时，本机出料传感器长时间感应到";
                            Enum下料机 = 下料机.无任务;
                            TonThisOutPCBTimeOut.IN = false;
                        }
                        break;

                    case 下料机.本机出料完成:
                        ThisReady = false;
                        Enum下料机 = 下料机.无任务;
                        break;

                    default:
                        break;
                }
                #endregion
            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 复位报警
        /// </summary>
        public void RestAlarm()
        {
            ErrInfo = string.Empty;
        }
        #endregion
    }
}
